package com.yeziji.utils;

import cn.hutool.core.util.StrUtil;
import com.yeziji.common.CommonSymbol;
import com.yeziji.constant.VariousStrPool;
import com.yeziji.utils.expansion.Lists2;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.function.Consumer;

/**
 * 控制台输入工具
 *
 * @author hwy
 * @since 2023/11/13 23:20
 **/
@Slf4j
@Data
public class ScannerChain {
    /**
     * 每个环节的输入提示语
     */
    private List<String> tips;

    /**
     * 记录提示消费行为
     */
    private Map<String, Consumer<String>> tipConsumerRecordMap;

    // no-parameter construction is prohibited
    private ScannerChain() {
    }

    /**
     * 开始构造输入链
     *
     * @return {@link ScannerChain} 输入链
     */
    public static ScannerChain start() {
        ScannerChain scannerChain = new ScannerChain();
        scannerChain.setTips(new ArrayList<>());
        scannerChain.setTipConsumerRecordMap(new HashMap<>());
        return scannerChain;
    }

    /**
     * 追加指令
     *
     * @param tip 指令输入提示语
     * @return {@link ScannerChain} 输入链
     */
    public ScannerChain add(String tip, Consumer<String> scannerConsumer) {
        this.tips.add(tip);
        if (scannerConsumer != null) {
            this.tipConsumerRecordMap.put(tip, scannerConsumer);
        }
        return this;
    }

    /**
     * 执行控制台输入
     */
    public String end(String successTip) {
        if (Lists2.isEmpty(this.tips)) {
            return VariousStrPool.EMPTY;
        }

        StringJoiner sj = new StringJoiner(CommonSymbol.COMMA);
        Scanner scanner = new Scanner(System.in);
        for (String tip : this.tips) {
            log.info(StrUtil.isBlank(tip) ? "请输入: " : tip);
            if (scanner.hasNext()) {
                String next = scanner.next();
                sj.add(next);
                Consumer<String> consumer = this.tipConsumerRecordMap.get(tip);
                if (consumer != null) {
                    consumer.accept(next);
                }
            }
        }

        // 完成后的结束语
        if (StrUtil.isNotBlank(successTip)) {
            log.info(successTip);
        } else {
            log.info("输入完成");
        }
        return sj.toString();
    }
}
